/*
 * MIT License
 *
 * Copyright (c) 2020 wen.gu <454727014@qq.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/***************************************************************************
 * Name: xtypes.h
 *
 * Purpose: base type define for communication
 *
 * Developer:
 *   wen.gu , 2023-10-25
 *
 * TODO:
 *
 ***************************************************************************/

#ifndef __XBUS_COM_XTYPES_H__
#define __XBUS_COM_XTYPES_H__

#include <cstdint>

#include "xbus/core/xtype.h"
#include "xbus/core/xresult.h"
#include "xbus/core/xutils.h"

#define XBUS_INVALID_XCOM_ID (-1)
#define XBUS_INVALID_MSG_ID (0)

#define XBUS_DISABLE_RECONNECTION (0)
#define XBUS_WORKER_PRIORITY_DEFAULT (0)
#define XBUS_MSG_QUEUE_SIZE_UNLIMIT (0)

namespace xbus::com {

using XComId = int64_t;
using MessageId = uint16_t;
using SequenceNumber = uint16_t;

enum class XComType: uint32_t {
    None = 0,
    UDS = core::XFourCC("UDS"),
    SHM = core::XFourCC("SHM"),
    TCP = core::XFourCC("TCP"),
    UDP = core::XFourCC("UDP"),
};

enum XMessageType: uint8_t {
    XMsg_TypeNone = 0,
    XMsg_TypeMethodRequest           = 0x01, /** (client --> service) the payload is the parameter of request (need response @see XMsg_TypeMethodResponse) */
    XMsg_TypeMethodRequestNoReturn   = 0x02, /** (client --> service) the payload is the parameter of request (needn't response)  */
    XMsg_TypeMethodResponse          = 0x03, /** (service --> client) the payload is the response data of request (needn't response)  */

    XMsg_TypeEvent                   = 0x04, /** (service --> client) the payload is the event content (needn't response)  */
    XMsg_TypeEventSubscribe          = 0x05, /** (client --> service) no payload, just message header only (need response @see XMsg_TypeEventSubscribeAck) */
    XMsg_TypeEventSubscribeGroup    = 0x06, /** (client --> service) the payload is a array of event id(message id must be aways 0). (need response @see XMsg_TypeEventSubscribeAck) */
    XMsg_TypeEventSubscribeAck       = 0x07, /** (service --> client) no payload, have return code, @see XMessageReturnCode (needn't response) */
    XMsg_TypeEventStopSubscribe      = 0x08, /** (client --> service) no payload, just message header only (need response @see XMsg_TypeEventStopSubscribeAck)*/
    XMsg_TypeEventStopSubscribeAck   = 0x09, /** (service --> client) no payload, have return code, @see XMessageReturnCode (needn't response) */

    XMsg_TypePropertySet             = 0x0a, /** (client --> service) the payload is the parameter of request (need response @see XMsg_TypePropertySetAck) */
    XMsg_TypePropertySetAck          = 0x0b, /** (service --> client) the payload is the response data of request, have return code, @see XMessageReturnCode (needn't response)  */
    XMsg_TypePropertyGet             = 0x0c, /** (client --> service) the payload is the parameter of request (need response @see XMsg_TypePropertyGet_Ack) */
    XMsg_TypePropertyGetAck          = 0x0d, /** (service --> client) the payload is the response data of request, have return code, @see XMessageReturnCode  (needn't response)  */
    XMsg_TypePropertyNotification    = 0x0e, /** (service --> client) the payload is the value content of property (needn't response)  */

    XMsg_TypePropertySubscribe        = 0x0f, /** (client --> service) no payload, just message header only (need response @see XMsg_TypePropertySubscribe_Ack) */
    XMsg_TypePropertySubscribeAck     = 0x10, /** (service --> client) no payload, have return code, @see XMessageReturnCode (needn't response) */
    XMsg_TypePropertyStopSubscribe    = 0x11, /** (client --> service) no payload, just message header only (need response @see XMsg_TypePropertyStop_Subscribe_Ack) */
    XMsg_TypePropertyStopSubscribeAck = 0x12, /** (service --> client) no payload, have return code, @see XMessageReturnCode (needn't response) */
};


struct XSessionStartParam {
    /** 
     * worker priority: 
     * range: 0 < 100
    */
    int32_t send_priority = XBUS_WORKER_PRIORITY_DEFAULT;
    int32_t recv_priority = XBUS_WORKER_PRIORITY_DEFAULT;
    uint32_t max_send_queue_size = XBUS_MSG_QUEUE_SIZE_UNLIMIT; /** if set as 0, inidicate unlimited this size */
    uint32_t max_recv_queue_size = XBUS_MSG_QUEUE_SIZE_UNLIMIT; /** if set as 0, inidicate unlimited this size */
};


struct XClientStartParam {
    XSessionStartParam session_param;
    /** reconnect_time_interval_ms: 
     *  == 0:   Will be not do reconnect when Xdialer disconnected from XListener
     *  > 0: Try to reconnect to XListener with this interval time
     */
    uint32_t reconnect_time_interval_ms = XBUS_DISABLE_RECONNECTION;
};

struct FindServiceHandle {
    uint64_t uid;
    bool operator==(const FindServiceHandle& other) const { return uid == other.uid; }
    bool operator<(const FindServiceHandle& other) const { return uid < other.uid; }
    FindServiceHandle& operator=(const FindServiceHandle& other) {
        uid = other.uid;
        return *this;
    }
};


} //namespace xbus::com


#endif /** !__XBUS_COM_XTYPES_H__ */